package org.proteored.miapeapi.xml.ge.adapter;

import java.util.List;
import java.util.Set;

import org.proteored.miapeapi.cv.ControlVocabularyManager;
import org.proteored.miapeapi.cv.ge.ElectrophoresisType;
import org.proteored.miapeapi.interfaces.Adapter;
import org.proteored.miapeapi.interfaces.DateAdapter;
import org.proteored.miapeapi.interfaces.ge.DirectDetection;
import org.proteored.miapeapi.interfaces.ge.GEAdditionalInformation;
import org.proteored.miapeapi.interfaces.ge.ImageAcquisition;
import org.proteored.miapeapi.interfaces.ge.ImageGelElectrophoresis;
import org.proteored.miapeapi.interfaces.ge.IndirectDetection;
import org.proteored.miapeapi.interfaces.ge.MiapeGEDocument;
import org.proteored.miapeapi.interfaces.ge.Protocol;
import org.proteored.miapeapi.interfaces.ge.Sample;
import org.proteored.miapeapi.xml.ge.autogenerated.GEDirectDetection;
import org.proteored.miapeapi.xml.ge.autogenerated.GEImage;
import org.proteored.miapeapi.xml.ge.autogenerated.GEImageAcquisition;
import org.proteored.miapeapi.xml.ge.autogenerated.GEIndirectDetection;
import org.proteored.miapeapi.xml.ge.autogenerated.GEMIAPEGE;
import org.proteored.miapeapi.xml.ge.autogenerated.GEProtocol;
import org.proteored.miapeapi.xml.ge.autogenerated.GESample;
import org.proteored.miapeapi.xml.ge.autogenerated.ObjectFactory;
import org.proteored.miapeapi.xml.ge.autogenerated.ParamType;
import org.proteored.miapeapi.xml.ge.util.GEControlVocabularyXmlFactory;

/**
 * Implementation of {@link GEMIAPEGE} from a {@link MiapeGEDocument} object.
 * 
 * @author Salva
 * 
 */
public class MiapeGeXMLAdapter implements Adapter<GEMIAPEGE> {
	private final ObjectFactory factory;
	private final MiapeGEDocument document;
	private final GEControlVocabularyXmlFactory cvFactory;

	public MiapeGeXMLAdapter(MiapeGEDocument document,
			ControlVocabularyManager controlVocabularyUtil) {
		this.factory = new ObjectFactory();
		this.document = document;
		this.cvFactory = new GEControlVocabularyXmlFactory(factory, controlVocabularyUtil);
	}

	@Override
	public GEMIAPEGE adapt() {
		GEMIAPEGE xmlMIAPEGE = factory.createGEMIAPEGE();

		addMiapeData(xmlMIAPEGE);

		Set<Sample> samples = document.getSamples();
		if (samples != null)
			addSamples(xmlMIAPEGE.getGESample(), samples);

		Set<Protocol> protocols = document.getProtocols();
		if (protocols != null)
			addProtocols(xmlMIAPEGE.getGEProtocol(), protocols);

		Set<DirectDetection> directDetections = document.getDirectDetections();
		if (directDetections != null)
			addDirectDetections(xmlMIAPEGE.getGEDirectDetection(), directDetections);

		Set<IndirectDetection> indirectDetections = document.getIndirectDetections();
		if (indirectDetections != null)
			addIndirectDetections(xmlMIAPEGE.getGEIndirectDetection(), indirectDetections);

		Set<ImageAcquisition> imageAcquisitions = document.getImageAcquisitions();
		if (imageAcquisitions != null)
			addImageAcquisitions(xmlMIAPEGE.getGEImageAcquisition(), imageAcquisitions);

		Set<ImageGelElectrophoresis> images = document.getImages();
		if (images != null)
			addImages(xmlMIAPEGE.getGEImage(), images);

		Set<GEAdditionalInformation> additionalInformations = document.getAdditionalInformations();
		if (additionalInformations != null)
			addAdditionalInformations(xmlMIAPEGE.getGEAdditionalInformation(),
					additionalInformations);

		return xmlMIAPEGE;
	}

	private void addAdditionalInformations(List<ParamType> geAdditionalInformation,
			Set<GEAdditionalInformation> additionalInformations) {
		if (additionalInformations == null)
			return;
		for (GEAdditionalInformation image : additionalInformations)
			geAdditionalInformation.add(new AdditionalInformationAdapter(image, factory, cvFactory)
					.adapt());

	}

	private void addImages(List<GEImage> geImage, Set<ImageGelElectrophoresis> images) {
		if (images == null)
			return;
		for (ImageGelElectrophoresis image : images)
			geImage.add(new ImageAdapter(image, factory, cvFactory).adapt());

	}

	private void addImageAcquisitions(List<GEImageAcquisition> geImageAcquisition,
			Set<ImageAcquisition> imageAcquisitions) {
		if (imageAcquisitions == null)
			return;
		for (ImageAcquisition imageAcquisition : imageAcquisitions) {
			geImageAcquisition
					.add(new ImageAcquisitionAdapter(imageAcquisition, factory, cvFactory).adapt());
		}
	}

	private void addIndirectDetections(List<GEIndirectDetection> geIndirectDetection,
			Set<IndirectDetection> indirectDetections) {
		if (indirectDetections == null)
			return;
		for (IndirectDetection indirectDetection : indirectDetections)
			geIndirectDetection.add(new IndirectDetectionAdapter(indirectDetection, factory,
					cvFactory).adapt());

	}

	private void addDirectDetections(List<GEDirectDetection> geDirectDetection,
			Set<DirectDetection> directDetections) {
		if (directDetections == null)
			return;
		for (DirectDetection directDetection : directDetections)
			geDirectDetection.add(new DirectDetectionAdapter(directDetection, factory, cvFactory)
					.adapt());

	}

	private void addProtocols(List<GEProtocol> geProtocol, Set<Protocol> protocols) {
		if (protocols == null)
			return;
		for (Protocol protocol : protocols) {
			geProtocol.add(new ProtocolAdapter(protocol, this.factory, this.cvFactory).adapt());
		}

	}

	private void addSamples(List<GESample> xmlSample, Set<Sample> samples) {
		if (samples == null)
			return;
		for (Sample sample : samples) {
			xmlSample.add(new SampleAdapter(this.factory, sample).adapt());
		}
	}

	private void addMiapeData(GEMIAPEGE xmlMIAPEGE) {
		if (document.getId() > 0) {
			xmlMIAPEGE.setId(document.getId());
		} else {
			xmlMIAPEGE.setId(-1);
		}
		if (document.getDate() != null)
			xmlMIAPEGE.setDate(document.getDate().getValue());
		if (document.getElectrophoresisType() != null)
			xmlMIAPEGE.setElectrophoresisType(cvFactory.createCV(document.getElectrophoresisType(),
					null, ElectrophoresisType.getInstance(cvFactory.getCvManager())));
		if (document.getContact() != null)
			xmlMIAPEGE.setGEContact(new ContactAdapter(document.getContact(), factory, cvFactory)
					.adapt());
		if (document.getModificationDate() != null)
			xmlMIAPEGE.setModificationDate(new DateAdapter(document.getModificationDate()).adapt());
		xmlMIAPEGE.setName(document.getName());
		xmlMIAPEGE.setAttachedFileLocation(document.getAttachedFileLocation());
		if (document.getProject() != null)
			xmlMIAPEGE.setMIAPEProject(new ProjectAdapter(document.getProject(), factory).adapt());

		if (document.getTemplate() != null)
			xmlMIAPEGE.setTemplate(document.getTemplate());

		xmlMIAPEGE.setVersion(document.getVersion());
	}
}
